#输出目录
binDir = bin
#目标文件目录
objDir = obj
#测试文件目录
testDir = test
#库文件源代码目录
libSrcDir = src/lib
#输出文件源代码目录
outSrcDir = src/out
#头文件源代码目录
includeDir = src/include
#测试源代码目录
testSrcDir = src/test
VPATH = $(binDir) $(objDir) $(libSrcDir) $(outSrcDir) $(includeDir) $(testSrcDir) $(testDir)

cc = g++
header = $(includeDir)
compile = $(cc) -c $(ccopt)
ccopt = -g -I $(header)
link = $(cc)
linkopt = -lws2_32
marco = -DECLIPSE
findDepend = $(cc) -I $(header) -MM

#测试源文件
testSrc = $(wildcard $(testSrcDir)/*.cpp)
#输出源文件
outSrc = $(wildcard $(outSrcDir)/*.cpp)
#库源文件
libSrc = $(wildcard $(libSrcDir)/*.cpp)
#输出exe
out = $(notdir $(patsubst %.cpp,%.exe,$(outSrc)))
#测试exe
testOut = $(notdir $(patsubst %.cpp,%.exe,$(testSrc)))
#库的.o,用于exe文件的链接
libs = $(patsubst %.cpp,%.o,$(notdir $(libSrc)))
#所有的.cpp
sources = $(notdir $(testSrc) $(outSrc) $(libSrc))
#所有的.o
objects = $(patsubst %.cpp,%.o,$(notdir $(sources)))
#所有的.d
deps = $(sources:.cpp=.d)

.PHONY : clean echo all mkdir

all : mkdir $(objects) $(testOut) $(out) echo

#解析依赖
$(deps) : %.d : %.cpp
	@echo analyze $@'s dependency
	@if exist $@ del $@
	@$(findDepend) $< > $@d
	@sed "s,\($*\)\.o[ :]*,\1.o $@ : ,g" < $@d > $@
	@del $@d

sinclude $(deps)$<

#创建obj和bin文件夹
mkdir :
	@if not exist $(binDir) mkdir $(binDir)
	@if not exist $(objDir) mkdir $(objDir)
	@if not exist $(testDir) mkdir $(testDir)

#对于所有的输出文件,链接其目标文件和其它lib的目标文件,输出到bin下
$(out) : %.exe: %.o $(libSrc)
	@if exist $< $(link) -o $(binDir)/$@ $< $(addprefix obj/,$(libs)) $(linkopt)
	@if not exist $< $(link) -o $(binDir)/$@ $(objDir)/$< $(addprefix obj/,$(libs)) $(linkopt)
	@echo link $@

#对于所有的测试文件,链接其目标文件和其它lib的目标文件,输出到test下
$(testOut) : %.exe: %.o $(libSrc)
	@if exist $< $(link) -o $(testDir)/$@ $< $(addprefix obj/,$(libs)) $(linkopt)
	@if not exist $< $(link) -o $(testDir)/$@ $(objDir)/$< $(addprefix obj/,$(libs)) $(linkopt)
	@echo link $@

#对所有的cpp,编译成目标文件,输出到obj下
$(objects) : %.o: %.cpp
	@$(compile) -o $(objDir)/$@ $<
	@echo compile $@

clean :
	@del /s *.o *.exe *.d *.dd
	@echo clean done

echo : 
	@echo make done
